package com.demo.utils.base;


import com.demo.utils.error.GlobalErrorEnum;
import com.demo.utils.error.IError;
import com.demo.utils.exception.BizServiceException;
import com.yomahub.tlog.context.TLogContext;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serializable;

/**
 * 操作消息提醒
 *
 * @author system
 */
@Data
public class WebResponse<T> implements Serializable {

    private static final int SUCCESS_CODE = GlobalErrorEnum.SUCCESS.getErrorCode();
    private static final String SUCCESS_MSG = GlobalErrorEnum.SUCCESS.getErrorMessage();
    private static final int DEFAULT_FAIL_CODE = GlobalErrorEnum.FAIL.getErrorCode();
    private static final int ERROR_CODE = GlobalErrorEnum.ERROR.getErrorCode();

    private static final long serialVersionUID = -8143500853386856828L;

    @Schema(description = "成功标识")
    private Boolean success = true;

    @Schema(description = "消息状态码")
    private Integer httpCode;

    @Schema(description = "消息内容")
    private String message;

    @Schema(description = "请求链路id")
    private String requestId = this.getTraceId();

    /**
     * 兼容旧版start
     **/
    @Schema(description = "状态")
    private String status = "success";

    @Schema(description = "状态码")
    private Integer statusCode;

    /**
     * 兼容旧版end
     **/

    @Schema(description = "返回数据")
    private T data;


    private WebResponse() {
        this.httpCode = SUCCESS_CODE;
        this.message = SUCCESS_MSG;
    }

    private WebResponse(IError error) {
        this.success = Boolean.FALSE;
        this.status = "error";
        this.httpCode = error.getErrorCode();
        this.message = error.getErrorMessage();
    }

    private WebResponse(Integer httpCode, String message) {
        this.success = Boolean.FALSE;
        this.status = "error";
        this.httpCode = httpCode;
        this.message = message;
    }

    private WebResponse(Integer httpCode, Integer statusCode, String message) {
        this.success = Boolean.FALSE;
        this.status = "error";
        this.httpCode = httpCode;
        this.message = message;
        this.statusCode = statusCode;
    }

    /**
     * 成功 无业务数据返回
     *
     * @return
     */
    public static WebResponse<Void> success() {
        return new WebResponse<>();
    }

    /**
     * 成功 返回泛型对象
     *
     * @param result 数据
     * @return
     */
    public static <T> WebResponse<T> success(T result) {
        WebResponse<T> response = new WebResponse();
        response.setData(result);
        return response;
    }


    public static <T> WebResponse<T> success(Integer code, String message) {
        return new WebResponse(code, message);
    }

    public static <T> WebResponse<T> success(Integer code, String message, T result) {
        WebResponse<T> response = new WebResponse(code, message);
        response.setData(result);
        response.setStatusCode(-1);
        return response;
    }

    /**
     * 失败返回
     *
     * @param error 错误类型
     * @return
     */
    public static <T> WebResponse<T> failure(IError error) {
        WebResponse<T> response = new WebResponse(error);
        return response;
    }

    /**
     * 失败返回
     *
     * @param error 错误类型
     * @param <T>   数据
     * @return
     */
    public static <T> WebResponse<T> failure(IError error, T result) {
        WebResponse<T> response = new WebResponse(error);
        response.setData(result);
        return response;
    }

    /**
     * 失败返回
     *
     * @param message 异常信息
     * @param code    错误码
     * @return
     */
    public static <T> WebResponse<T> failure(Integer code, String message) {
        if (code == null) {
            code = DEFAULT_FAIL_CODE;
        }
        WebResponse<T> response = new WebResponse(code, message);
        return response;
    }

    /**
     * 失败返回
     *
     * @param message 异常信息
     * @param code    错误码
     * @param result  数据
     * @param <T>
     * @return
     */
    public static <T> WebResponse<T> failure(Integer code, String message, T result) {
        WebResponse<T> response = new WebResponse(code, message);
        response.setData(result);
        return response;
    }

    /**
     * 返回错误消息
     *
     * @return
     */
    public static WebResponse error() {
        return WebResponse.error(GlobalErrorEnum.ERROR);
    }

    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static WebResponse error(String msg) {
        return WebResponse.error(ERROR_CODE, msg);
    }

    /**
     * 返回错误消息
     *
     * @param code
     * @param msg
     * @return
     */
    public static WebResponse error(Integer code, String msg) {
        return new WebResponse(GlobalErrorEnum.RETURN_STATUS_CODE_ERROR.getErrorCode(), code, msg);
    }

    /**
     * 返回错误消息
     *
     * @param errorEnum 返回内容
     * @return 警告消息
     */
    public static WebResponse error(GlobalErrorEnum errorEnum) {
        return new WebResponse(GlobalErrorEnum.RETURN_STATUS_CODE_ERROR.getErrorCode(), errorEnum.getErrorCode(), errorEnum.getErrorMessage());
    }

    /**
     * 返回错误消息
     *
     * @param e 异常
     * @return 警告消息
     */
    public static WebResponse error(BizServiceException e) {
        if (null != e.getHttpCode()) {
            return new WebResponse(e.getHttpCode(), e.getCode(), e.getMessage());
        }
        return new WebResponse(GlobalErrorEnum.RETURN_STATUS_CODE_ERROR.getErrorCode(), e.getCode(), e.getMessage());
    }


    /**
     * 返回错误消息
     *
     * @param msg 返回内容
     * @return 警告消息
     */
    public static WebResponse errorStatusCode(String msg, Integer statusCode) {
        return new WebResponse(ERROR_CODE, statusCode, msg);
    }

    public Integer getStatusCode() {
        if (this.statusCode != null) {
            return this.statusCode;
        } else if (getHttpCode() != null && getHttpCode() != 200) {
            return getHttpCode();
        } else if (getHttpCode() == null) {
            return 500;
        } else {
            return 0;
        }
    }

    public String getTraceId() {
        return TLogContext.getTraceId();
    }
}
